<?php

namespace frontend\models;

use Yii\base\Component;
use React\EventLoop\Factory;
use React\Socket\Server;
use React\Socket\ConnectionInterface;

class TelnetModel extends Component
{
    private $port = 8765;
    private $host = "0.0.0.0";

    private $loop;
    private $socket;

    public function init()
    {
        parent::init();
        $this->loop = React\EventLoop\Factory::create();
    }

    public function stop()
    {
        if($this->socket){
            $this->socket->close();
        }
        if($this->loop){
            $this->loop->stop();
        }
    }

    public function start()
    {
        $this->socket = new Server("{$this->host}:{$this->port}",$this->loop);

        $this->socket->on('connection',function (ConnectionInterface $connection){
            $this->handleConnection($connection);

            $this->loop->run();
        });
    }

    private function handleConnection(ConnectionInterface $connection)
    {
        $address = $connection->getRemoteAddress();

        $connection->write("hello");

        $connection->on('data',function ($data) use ($connection){
           $this->handleData($connection,$data);
        });

        $connection->on('close',function ($data) use ($address){
            echo "断开";
        });

    }

    private function handleData(ConnectionInterface $connection,$data)
    {
        $inputData = trim($data);

        echo "命令：".$inputData;

        if(strpos(strtolower($inputData),"mul") ===0){
            $this->mulData($connection,$inputData);
        }if(strpos(strtolower($inputData),"conv_tree") ===0){
            $this->convTree($connection,$inputData);
        }else{
            $connection->write("错误命令");
        }

    }

    private function mulData(ConnectionInterface $connection,$inputData)
    {
        $numbers = preg_split('/\s+/', $inputData);

        if(count($numbers) !== 3){
            $connection->write("错误命令!");
            return ;
        }
        $x = $numbers[1];
        $y = $numbers[2];

        if(!is_numeric($x) || !is_numeric($y)){
            $connection->write("错误命令!!");
            return ;
        }

        $result = floatval($x) * floatval($y);
        $connection->write("计算结果等于:".$result);
    }


    private function convTree(ConnectionInterface $connection,$inputData)
    {
        $tree = [];
        $idPaths = [];

        foreach ($inputData as $jsonStr){
            $item = json_decode($jsonStr, true);
            $namePath = explode(",", $item["namePath"]);

            $levelOne = $namePath[0];
            $levelTwo = $namePath[1];
            $levelThree = $namePath[3];

            if(!isset($tree[$levelOne])){
                $idPath = Yii::$app->security->generateRandomString(10);
                $tree[$levelOne] = [
                    'id' => $idPath,
                    'id_path' => $idPath,
                    'is_leaf' => 2,
                    'level' => 1,
                    'name' => $item['name'],
                    'name_path' => $item['name_path'],
                    'parent_id' => 0,
                    'children' => []
                ];
                $idPaths[$levelOne] = $idPath;
            }

            if(!isset($tree[$levelOne]['children'][$levelTwo])){
                $idPath = Yii::$app->security->generateRandomString(10);
                $idPath2 = $idPaths[$levelOne] . ',' . $idPath;

                $tree[$levelOne]['children'][$levelTwo] = [
                    'id' => $idPath,
                    'id_path' => $idPath2,
                    'is_leaf' => 2,
                    'level' => 2,
                    'name' => $item['name'],
                    'name_path' => $item['name_path'],
                    'parent_id' => $idPaths[$levelOne],
                    'children' => []
                ];

                $idPaths[$levelOne . ',' . $levelTwo] = $idPath2;
            }


            $idPath = Yii::$app->security->generateRandomString(10);
            $idPath3 = $idPaths[$levelOne . ',' . $levelTwo] . ',' . $idPath;
            $tree[$levelOne]['children'][$levelTwo]['children'][] = [
                    'id' => $item['id'],
                    'id_path' => $idPath3,
                    'is_leaf' => 2,
                    'level' => 3,
                    'name' => $item['name'],
                    'name_path' => $item['name_path'],
                    'parent_id' => $idPaths[$levelOne . ',' . $levelTwo],
                    'children' => []
                ];
        }

        $result = array_values($tree);
        foreach ($result as &$levelOne){
            $levelOne['children'] = array_values($levelOne['children']);
        }
        $connection->write("树结构为:".$result);
    }

}